package com.yuexunit.finance.news.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import com.yuexunit.core.BusinessException;
import com.yuexunit.finance.common.util.DateUtils;
import com.yuexunit.finance.news.entity.NewsCategoryEntity;
import com.yuexunit.finance.news.entity.NewsContentEntity;
import com.yuexunit.finance.news.entity.NewsEntity;
import com.yuexunit.finance.news.entity.lexicon.CategoryTypeEnum;
import com.yuexunit.inject.annotation.Implements;
import com.yuexunit.page.PageCriteria;
import com.yuexunit.page.PageList;
import com.yuexunit.persist.PersistUtil;
import com.yuexunit.persist.annotation.Transactional;
import com.yuexunit.util.DateUtil;

/**
 * Created by HuangYH on 2015/9/22
 */
@Implements(NewsService.class)
public class NewsServiceImpl implements NewsService {

	@Override
	@Transactional
	public Long createNews(NewsEntity newsEntity) {
		newsEntity.setEnabled(true);
		newsEntity.setCreateDateTime(DateUtil.now());
		newsEntity.setUpdateDateTime(DateUtil.now());
		PersistUtil.insert(newsEntity);
		if (newsEntity.getContents() == null) {
			return newsEntity.getNewsId();
		}
		for (NewsContentEntity content : newsEntity.getContents()) {
			content.setNewsId(newsEntity.getNewsId());
			PersistUtil.insert(content);
		}
		return newsEntity.getNewsId();
	}

	@Override
	@Transactional
	public void updateNews(NewsEntity newsEntity) {
		NewsEntity news = inquireNewsDetail(newsEntity.getNewsId());
		news.setNewsCategoryId(newsEntity.getNewsCategoryId());
		news.setNewsTitle(newsEntity.getNewsTitle());
		news.setSummary(newsEntity.getSummary());
		news.setImageUuid(newsEntity.getImageUuid());
		news.setNewsSource(newsEntity.getNewsSource());
		news.setRecommend(newsEntity.getRecommend());
		news.setNewsSourceLink(newsEntity.getNewsSourceLink());
		news.setPublisherId(newsEntity.getPublisherId());
		news.setPublisher(newsEntity.getPublisher());
		news.setUpdateDateTime(DateUtil.now());
		PersistUtil.update(news);
		if (news.getContents() == null) {
			return;
		}
		for (NewsContentEntity content : newsEntity.getContents()) {
			if (content.getNewsContentId() != null) {
				NewsContentEntity entity = PersistUtil.get(NewsContentEntity.class, content.getNewsContentId());
				entity.setContent(content.getContent());
				entity.setFileUuid(content.getFileUuid());
				entity.setSequence(content.getSequence());
				PersistUtil.update(entity);
			} else {
				content.setNewsId(news.getNewsId());
				PersistUtil.insert(content);
			}
		}
	}

	@Override
	@Transactional
	public void disableNews(Long newsId) {
		NewsEntity e = inquireNewsDetail(newsId);
		e.setEnabled(false);
		e.setUpdateDateTime(DateUtil.now());
		PersistUtil.update(e);
	}

	@Override
	@Transactional
	public void recommendNews(Long newsId) {
		NewsEntity e = inquireNewsDetail(newsId);
		e.setRecommend(true);
		e.setUpdateDateTime(DateUtil.now());
		PersistUtil.update(e);
	}

	@Override
	@Transactional
	public void disableRecommendNews(Long newsId) {
		NewsEntity e = inquireNewsDetail(newsId);
		e.setRecommend(false);
		e.setUpdateDateTime(DateUtil.now());
		PersistUtil.update(e);
	}

	@Override
	public NewsEntity inquireNewsDetail(Long newsId) {
		NewsEntity e = PersistUtil.get(NewsEntity.class, newsId);
		if (e == null || !e.getEnabled()) {
			throw new BusinessException("资讯信息未找到");
		}
		return e;
	}

	@Override
	public NewsEntity inquireNews(Long newsId) {
		return PersistUtil.get(NewsEntity.class, newsId);
	}

	@Override
	public PageList<NewsEntity> inquireNewsPageList(Long newsCategoryId, Boolean recommend, String newsTitle, String publisher, PageCriteria page, String issueDateFromTime, String issueDateToTime, boolean all) {
		List<Long> newsCategoryIds = null;
		if (!all) {
			if (newsCategoryId == null) {
				DetachedCriteria dc = DetachedCriteria.forClass(NewsCategoryEntity.class);
				dc.add(Restrictions.eq("categoryType", CategoryTypeEnum.INFORMATION));
				dc.add(Restrictions.eq("enabled", Boolean.TRUE));
				dc.setProjection(Projections.property("newsCategoryId"));
				newsCategoryIds = PersistUtil.get(dc);
				if (newsCategoryIds.isEmpty()) {
					return new PageList<NewsEntity>(page, 0);
				}
			} else {
				newsCategoryIds = new ArrayList<>(1);
				newsCategoryIds.add(newsCategoryId);
			}
		}

		DetachedCriteria dc = DetachedCriteria.forClass(NewsEntity.class);
		if (newsCategoryIds != null && !newsCategoryIds.isEmpty()) {
			dc.add(Restrictions.in("newsCategoryId", newsCategoryIds));
		}
		if (recommend != null) {
			dc.add(Restrictions.eq("recommend", recommend));
		}
		if (StringUtils.isNotBlank(newsTitle)) {
			dc.add(Restrictions.like("newsTitle", "%" + newsTitle + "%"));
		}
		if (StringUtils.isNotBlank(publisher)) {
			dc.add(Restrictions.like("publisher", "%" + publisher + "%"));
		}
		dc.add(Restrictions.eq("enabled", true));
		if (StringUtils.isNotBlank(issueDateFromTime)) {
			dc.add(Restrictions.gt("updateDateTime", DateUtils.formatBeginDay(issueDateFromTime)));
		}
		if (StringUtils.isNotBlank(issueDateToTime)) {
			dc.add(Restrictions.lt("updateDateTime", DateUtils.formatBeginDay(issueDateToTime)));
		}

		dc.addOrder(Order.desc("updateDateTime"));
		PageList<NewsEntity> newsPageList = PersistUtil.get(dc, page);
		return newsPageList;
	}

	@Override
	public List<NewsContentEntity> inquireNewsContentList(Long newsId) {
		DetachedCriteria dc = DetachedCriteria.forClass(NewsContentEntity.class);
		dc.add(Restrictions.eq("newsId", newsId));
		return PersistUtil.get(dc);
	}

	@Override
	public PageList<NewsEntity> inquireHelpPageList(String content, PageCriteria page) {
		DetachedCriteria dc = DetachedCriteria.forClass(NewsCategoryEntity.class);
		dc.add(Restrictions.eq("categoryType", CategoryTypeEnum.HELP));
		dc.add(Restrictions.eq("enabled", Boolean.TRUE));
		dc.setProjection(Projections.property("newsCategoryId"));
		List<Long> newsCategoryIds = PersistUtil.get(dc);
		if (newsCategoryIds.isEmpty()) {
			return new PageList<NewsEntity>(page, 0);
		}
		dc = DetachedCriteria.forClass(NewsContentEntity.class);
		dc.add(Restrictions.in("newsCategoryId", newsCategoryIds));
		dc.add(Restrictions.like("content", "%" + content + "%"));
		dc.setProjection(Projections.projectionList().add(Projections.groupProperty("newsId")));
		List<Long> newsIds = PersistUtil.get(dc);

		dc = DetachedCriteria.forClass(NewsEntity.class);
		dc.add(Restrictions.in("newsCategoryId", newsCategoryIds));
		if (newsIds.isEmpty()) {
			if(StringUtils.isNotBlank(content)){
				dc.add(Restrictions.or(Restrictions.like("newsTitle", "%" + content + "%"), Restrictions.like("summary", "%" + content + "%")));
			}
		} else {
			if(StringUtils.isNotBlank(content)){
				dc.add(Restrictions.or(Restrictions.like("newsTitle", "%" + content + "%"), Restrictions.like("summary", "%" + content + "%"), Restrictions.in("newsId", newsIds)));
			}
			}
		return PersistUtil.get(dc, page);
	}
}
